package modules.ulock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 锁的理解
 *   自旋锁
 *
 * @author shengren.yan
 * @create 2021-04-16
 */
public class ULock2 {
    public static void main(String[] args) throws Exception{

        //使用CAS实现自旋锁
        SpinlockDemo lock = new SpinlockDemo();
        new Thread(() -> {
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myunlock();
            }
        }, "线程A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myunlock();
            }
        }, "线程B").start();

        // 线程A 先拿到锁，B锁在自旋中，A解锁后，B跳出自旋循环，B开始解锁
    }
}

// 自己写的自旋锁
class SpinlockDemo {

    // int   类型 默认值是 0
    //thread 类型 默认值是 null
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    //加锁
    public void myLock() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "===> mylock");

        // 自旋锁
        // 如果当前对象是null,比较替换成对象，执行结果为false ,就一直循环
        while (!atomicReference.compareAndSet(null, thread)) {
//            System.out.println(Thread.currentThread().getName() + " ==> 自旋中~");
        }

    }


    //解锁
    public void myunlock() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "===> myUnlock");
        atomicReference.compareAndSet(thread, null);
    }

}
